package com.example.demo.person.web;

import com.example.demo.common.response.SSPResponse;
import com.example.demo.common.response.SSPTResponse;
import com.example.demo.person.dto.AdvanceQueryPersonDTO;
import com.example.demo.use_demo.a_excel_demo.entity.ExcelImportResult;
import com.example.demo.use_demo.a_fork_join.ExcelForkTask;
import com.example.demo.use_demo.a_remote_service.RemoteSync;
import com.example.demo.use_demo.a_rrate_limiter.PersonModifyLimit;
import com.example.demo.person.dto.PersonDTO;
import com.example.demo.person.pojo.Person;
import com.example.demo.person.service.IPersonService;
import com.example.demo.person.service.PersonServiceImpl;
import com.example.demo.common.request.SSPPageRequest;
import com.example.demo.person.vo.PersonVO;
import com.github.pagehelper.PageInfo;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.owasp.esapi.ESAPI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;

/**
 * @author zhangqiang
 * @date 2021/5/30 12:05
 */
@RequestMapping("/person")
@RestController
public class PersonController {

    @Autowired
    private PersonServiceImpl personServiceImpl;

    @Autowired
    private IPersonService personService;

    @Autowired
    private RemoteSync remoteSync;

    /**
     * 保存
     */
    @PersonModifyLimit(permits = 1, waitingTime = 0, timeUnit = TimeUnit.SECONDS)
    @PostMapping("save")
    public SSPResponse savePerson(@RequestBody @Validated PersonDTO personDTO) {
        personServiceImpl.savePerson(personDTO);
        return SSPResponse.success();
    }

    /**
     * 更新
     */
    @PersonModifyLimit(permits = 1, waitingTime = 0, timeUnit = TimeUnit.SECONDS)
    @PostMapping("update")
    public SSPResponse updatePerson(@RequestBody @Validated PersonDTO personDTO) {
        personServiceImpl.updatePerson(personDTO);
        return SSPResponse.success();
    }

    /**
     * 列表查询
     */
    @PostMapping("listByAdvanceQuery")
    public PageInfo<PersonVO> listByAdvanceQuery(@RequestBody SSPPageRequest<AdvanceQueryPersonDTO> queryParam) {
        return personServiceImpl.listByAdvanceQuery(queryParam);
    }

    /**
     * 查询
     */
    @GetMapping("tempQuery")
    public List<Person> tempQuery() {
        return personServiceImpl.tempQuery();
    }

    //----------------------------------------------------Excel---------------------------------------------------------

    /**
     * Domain-HuTool导入
     */
    @PostMapping("importDomainHuTool")
    public ExcelImportResult importDomainHuTool(@RequestPart("file") MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            return personServiceImpl.importDomainHuTool(inputStream);
        } catch (Exception e) {
            return new ExcelImportResult();
        }
    }

    /**
     * Domain-EasyExcel导入
     */
    @PostMapping("importDomainEasyExcel")
    public ExcelImportResult importDomainEasyExcel(@RequestPart("file") MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            return personServiceImpl.importDomainEasyExcel(inputStream);
        } catch (Exception e) {
            return new ExcelImportResult();
        }
    }

    /**
     * Person-EasyExcel导入
     */
    @PostMapping("importPersonsEasyExcel")
    public ExcelImportResult importPersonsEasyExcel(@RequestPart("file") MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            return personServiceImpl.importPersonEasyExcel(inputStream);
        } catch (Exception e) {
            return new ExcelImportResult();
        }
    }

    /**
     * Map-EasyExcel导入
     */
    @PostMapping("importMapEasyExcel")
    public ExcelImportResult importMapEasyExcel(@RequestPart("file") MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            return personServiceImpl.importMapEasyExcel(inputStream);
        } catch (Exception e) {
            return new ExcelImportResult();
        }
    }

    /**
     * Person-ForkJoin导入
     */
    @GetMapping("forkJoinReadExcel")
    public List<Person> forkJoinRead() throws Exception {
        File file = new File("D:\\Softs\\IDEA_WorkSpace\\easyexcelcover\\src\\main\\resources\\Person.xlsx");
        FileInputStream inputStream = new FileInputStream(file);
        XSSFWorkbook workbook = new XSSFWorkbook(inputStream);

        ForkJoinPool forkJoinPool = new ForkJoinPool(4);
        XSSFSheet sheetAt = workbook.getSheetAt(0);
        ExcelForkTask excelForkTask = new ExcelForkTask(1, sheetAt.getLastRowNum(), 2, sheetAt);
        return forkJoinPool.invoke(excelForkTask);
    }

    /**
     * Person-HuTool导出
     */
    @PostMapping("exportLoopWriteHuTool")
    public void exportLoopWriteHuTool(HttpServletResponse response) {
        personServiceImpl.exportLoopWriteHuTool(response);
    }

    /**
     * Person-EasyExcel导出
     */
    @PostMapping("exportEasyExcel")
    public void exportEasyExcel(HttpServletResponse response) throws Exception {
        personServiceImpl.exportEasyExcel(response);
    }

    /**
     * Person-EasyExcel导出
     */
    @PostMapping("exportLoopWriteEasyExcel")
    public void exportLoopWriteEasyExcel(HttpServletResponse response) {
        personServiceImpl.exportLoopWriteEasyExcel(response);
    }

    /**
     * 图片导入
     */
    @PostMapping("importPersonHeadImage")
    public String importPersonHeadImage(@RequestPart("file") MultipartFile file) {
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            return "IO异常";
        }
        return personServiceImpl.importPersonHeadImage(inputStream);
    }

    /**
     * 图片下载
     */
    @GetMapping("downloadPersonHeadImage")
    public void downloadPersonHeadImage(@RequestParam("fileName") String fileName, HttpServletResponse response) throws Exception {
        personServiceImpl.downloadPersonHeadImage(fileName,response);
    }
    //-----------------------------------------------------多线程-------------------------------------------------------

    /**
     * 根据条件查询 (异步多线程)
     */
    @PostMapping("getByLevels")
    public SSPTResponse<List<PersonVO>> getPersonsByLevels(@RequestBody List<String> levels){
        SSPTResponse<List<PersonVO>> ssptResponse = new SSPTResponse<>();
        ssptResponse.setData(personServiceImpl.getPersonsByLevels(levels));
        return ssptResponse;
    }

    /**
     * 根据条件更新 (异步多线程)
     */
    @PostMapping("updateByLevels")
    public void updatePersonsByLevels(@RequestBody List<String> levels){
        personServiceImpl.updatePersonsByLevels(levels);
    }

    //-----------------------------------------------------Redis--------------------------------------------------------

    /**
     * 设置人员分数
     * @param pId   人员ID
     * @param score 人员分数
     */
    @GetMapping("setPersonScore")
    public void setPersonScore(@RequestParam("pId") Long pId, @RequestParam("score") Long score){
        personService.setPersonScore(pId,score);
    }

    /**
     * 移除人员分数
     * @param pId  人员ID
     */
    @GetMapping("remPersonScore")
    public void remPersonScore(@RequestParam("pId") Long pId){
        personService.remPersonScore(pId);
    }

    /**
     * 获取人员分数排名
     */
    @GetMapping("getPersonScoreRanking")
    public SSPTResponse<Set<String>> getPersonRanking(){
        SSPTResponse<Set<String>> ssptResponse = new SSPTResponse<>();
        ssptResponse.setData(personService.getPersonRanking());
        return ssptResponse;
    }

    /**
     * 点赞
     */
    @GetMapping("like")
    public void like(@RequestParam("articleId")Long articleId){
        personService.like(articleId);
    }

    /**
     * 取消点赞
     */
    @GetMapping("cancelLike")
    public void cancelLike(@RequestParam("articleId")Long articleId){
        personService.cancelLike(articleId);
    }


    /**
     * 获取点赞数量
     */
    @GetMapping("getLikedCount")
    public SSPTResponse<Long> getLikedCount(@RequestParam("articleId")Long articleId){
        SSPTResponse<Long> ssptResponse = new SSPTResponse<>();
        ssptResponse.setData(personService.getLikedCount(articleId));
        return ssptResponse;
    }

    /**
     * 远程数据同步测试
     */
    @GetMapping("remoteSync")
    public SSPResponse remoteSync(){
        remoteSync.syncAward();
        return SSPResponse.success();
    }
}
